package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.heima.article.service.ApArticleContentService;
import com.heima.article.service.ApArticleHtmlService;
import com.heima.article.service.ApArticleService;
import com.heima.common.constants.ArticleConstants;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.search.vos.SearchArticleVo;
import freemarker.template.Configuration;
import freemarker.template.Template;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class ApArticleHtmlServiceImpl implements ApArticleHtmlService {

    @Autowired
    private ApArticleContentService apArticleContentService;

    @Autowired
    private Configuration configuration;

    @Autowired
    private FileStorageService fileStorageService;

    @Autowired
    private ApArticleService apArticleService;

    @Autowired
    private KafkaTemplate kafkaTemplate;

    /**
     * 生成文章页（生成详情页、上传MinIO、更新URL）
     * @param articleId
     * @param contentJSON
     */
    @GlobalTransactional
    @Async("taskExecutor")
    @Override
    public void generateHtml(Long articleId, String contentJSON) {
        try {
            //1.为FreeMarker的文章详情模板准备数据
            //1.1 将JSON数组字符串转为JSON数组对象
            JSONArray content = JSONArray.parseArray(contentJSON);

            //1.2 将JSON数组数据存入Map中
            Map data = new HashMap();
            data.put("content",content);

            //2.使用FreeMarker的静态渲染方式生成文章详情页
            //2.1 构建输出流对象
            StringWriter out = new StringWriter();

            //2.2 获取模板对象
            Template template = configuration.getTemplate("article.ftl");

            //2.3 生成文章详情页到输出流
            template.process(data,out);

            //3.将文章详情页上传到MinIO中
            //3.1 将输出流转为输入流
            ByteArrayInputStream in = new ByteArrayInputStream(out.toString().getBytes(StandardCharsets.UTF_8));

            //3.2 上传文章详情页数据到MinIO得到URL
            String url = fileStorageService.uploadHtmlFile("", articleId + ".html", in);

            //4.更新文章主表的详情页访问地址
            //4.1 构建更新对象
            ApArticle apArticleDB = new ApArticle();
            apArticleDB.setId(articleId); //更新条件
            apArticleDB.setStaticUrl(url);//更新的数据

            //4.2 调用updateById方法执行更新   update ap_article set static_url=? where id=?
            boolean result = apArticleService.updateById(apArticleDB);
            log.info("[生成文章页]生成详情页、上传并更新，结果：{}，文章id:{}" , result, articleId);

            //5.生产文章JSON数据到Kafka主题中
            ApArticle apArticle = apArticleService.getById(articleId);
            SearchArticleVo searchArticleVo = new SearchArticleVo();
            BeanUtils.copyProperties(apArticle,searchArticleVo);
            searchArticleVo.setContent(contentJSON);

            kafkaTemplate.send(ArticleConstants.ARTICLE_ES_SYNC_TOPIC, JSON.toJSONString(searchArticleVo));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
